package networks;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TcpEchoServer {
    private ServerSocket serverSocket = null;

    // 这里根据端口号创建对象
    public TcpEchoServer(int port) throws IOException {
        serverSocket = new ServerSocket(port);
    }

    public void start() throws IOException {
        System.out.println("服务器启动...");

        ExecutorService threadPool = Executors.newCachedThreadPool();

        while(true){
            // 这里需要先处理TCP的连通
            // 后续操作的就是这个clientServer对象

            // 主线程来accept
            Socket clientSocket = serverSocket.accept();

            // 每创建一个新的连接，就创建一个新的线程响应客户端的请求（多线程方式）
            // Thread t = new Thread(()->{
               // processConnection(clientSocket);
            // });
            // t.start();

            // 线程池方式
            threadPool.submit(()->{
                processConnection(clientSocket);
            });
        }
    }

    // 实现一次连接处理多个请求，同时可以处理多个客户端的请求
    private void processConnection(Socket clientSocket){

        System.out.printf("[%s:%d]客户端上线\n", clientSocket.getInetAddress(), clientSocket.getPort());

        try(InputStream inputStream = clientSocket.getInputStream();
            OutputStream outputStream = clientSocket.getOutputStream();
            // 使用Scanner和PrintWriter实现文件读写
            Scanner reader = new Scanner(inputStream);
            PrintWriter writer = new PrintWriter(outputStream)){

            // 一次连接处理多个请求
            while(true){
                // 1. 读取请求并解析
                // 如果没有请求，则断开连接并返回
                if(!reader.hasNext()){
                    System.out.println("连接断开...");
                    break;
                }

                // 使用Scanner读
                String request = reader.next();

                // 使用InputStream读
                // byte[] bytes = new byte[1024];
                // int n = inputStream.read(bytes);
                // if(n > 0){
                   // String request = new String(bytes, 0, n);
                // }

                // 2. 计算相应
                String response = process(request);

                // 3. 把响应返回到客户端
                writer.println(response);
                writer.flush();

                // 4. 打印日志
                System.out.printf("[%s:%d] req: %s; resp: %s\n", clientSocket.getInetAddress(), clientSocket.getPort(),
                        request, response);
            }

        }catch(IOException e){
            throw new RuntimeException();
        }finally {
            // 每次都会创建一个新的clientSocket，因此需要手动关闭
            try {
                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private String process(String request) {
        return request;
    }

    public static void main(String[] args) throws IOException {
        TcpEchoServer server = new TcpEchoServer(9090);
        server.start();
    }
}